# -*- coding:utf-8 -*-
# @Time : 21-9-24 上午8:31 
# @Author : zdy
# @File : ReportPDF.py
# desc:
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Paragraph, SimpleDocTemplate, Table, TableStyle
from reportlab.lib.units import inch
from reportlab.lib import colors
from reportlab.platypus.doctemplate import BaseDocTemplate, Frame
from reportlab.platypus import PageTemplate
from reportlab.lib.colors import HexColor
from reportlab.lib.units import cm
import os
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.pdfmetrics import registerFontFamily
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.lib.pagesizes import letter, landscape, A4

from Class.VoltSignal import dataBase
from Class.Format import Format
from Class.Factor import Factor

pdfmetrics.registerFont(TTFont('FZHTK', 'FZHTK.TTF'))  # 默认不支持中文，需要注册字体
gshowpageHeader = False
gpageHeader = ""
class ReportTemplate(object):
    def __init__(self):
        self.resultcolShow = []
        self.bstatic = False
        self.showtitle = True
        self.title ="结果"
        self.landspase = True
        self.name = "默认"
        self.showpageHeader = False
        self.pageHeader = ""

def table_model(model, reporttemplate:ReportTemplate):
    """
    ResultMode转为list
    :param model: 待转为list的ResultMode
    :param cols: 待转显示的列
    :return:list
    """
    model_table = []  # 存放每行数据
    # <editor-fold desc="写入列头">
    row0 = []
    for i in reporttemplate.resultcolShow:
        caption = model.horizontalHeaderItem(i).data(0)
        row0.append(caption)
    model_table.append(row0)
    # </editor-fold>
    statiList = []  # 保存各列数据，每一列是个list,作为这里的一个元素
    for i in range(len(reporttemplate.resultcolShow)):
        statiList.append([])
    rowCount = model.rowCount()
    for j in range(rowCount):
        colCurrent = 0  # 当前要写入的列
        rowCurrent = []  # 当前行内容
        for k in reporttemplate.resultcolShow:
            value = model.item(j, k).data(0)
            if k in dataBase.colresultNum:
                rowCurrent.append(Format.result(value, True))
                statiList[colCurrent].append(value)
            elif k in dataBase.colareaNum:
                rowCurrent.append(Format.area(value))
                statiList[colCurrent].append(value)
            elif k in dataBase.colweightNum:
                rowCurrent.append(Format.weight(value))
                statiList[colCurrent].append(value)
            else:
                rowCurrent.append(str(value))
            colCurrent += 1
        model_table.append(rowCurrent)
    if reporttemplate.bstatic:
        rowAverage = []
        rowSD = []
        rowRSD = []
        for index, valueList in enumerate(statiList):
            if index == 0:
                rowAverage = ["平均值"]
                rowSD = ["SD"]
                rowRSD = ["RSD"]
                continue
            if len(valueList) != 0:
                average = Factor.calculateAverage(valueList)
                sd = Factor.calculateDeviation(valueList)
                rsd = Factor.calculateRSD(sd, average)
                rowAverage.append(Format.result(average, True))
                rowSD.append(Format.result(sd, True))
                rowRSD.append(Format.percent(rsd, True))
            else:
                rowAverage.append("")
                rowSD.append("")
                rowRSD.append("")
        model_table.append(rowAverage)
        model_table.append(rowSD)
        model_table.append(rowRSD)
    return model_table


def exportPDF(path, models,  reporttemplate: ReportTemplate):
    if reporttemplate.landspase:
        size = landscape(A4)
    else:
        size = A4
    pdf = BaseDocTemplate(path,
                          pagesize=size,
                          rightMargin=1.5 * cm,
                          leftMargin=1.5 * cm,
                          topMargin=2 * cm,
                          bottomMargin=2 * cm,
                          showBoundary=False)  # 不显示Frame边界
    frame1 = Frame(x1=pdf.leftMargin, y1=pdf.topMargin,
                   width=pdf.width, height=pdf.height,
                   leftPadding=0, rightPadding=0,
                   topPadding=0, bottomPadding=0,
                   id='frame1')  # x1 左边距  y1 上边距
    global gshowpageHeader, gpageHeader
    gshowpageHeader = reporttemplate.showpageHeader
    gpageHeader = reporttemplate.pageHeader
    ltemplate = PageTemplate(id='t1', frames=[frame1], onPage=header, )
    pdf.addPageTemplates(ltemplate)
    Style = getSampleStyleSheet()
    content = []
    if reporttemplate.showtitle:
        titleStyle = Style['Title']
        # 自带样式不支持中文，需要设置中文字体，但有些样式会丢失，如斜体Italic。有待后续发现完全兼容的中文字体
        titleStyle.fontName = 'FZHTK'
        titleStyle.leading =50  # 该属性是设置行距
        content = [Paragraph(reporttemplate.title, titleStyle), Paragraph("", titleStyle)]
    tableContent = Style['Normal']
    tableContent.fontName = 'FZHTK'
    tableContent.wordWrap = 'CJK'
    colWidths = (pdf.width / len(reporttemplate.resultcolShow))  # 每列的宽度:每列宽度相同
    for model in models:
        model_table = table_model(model, reporttemplate)
        style = [
            # （列号，行号）-1表示最后列或者最后一行
            ('ALIGN', (0, 0), (-1, -1), 'CENTER'),  # 所有单元格都左右中间对齐
            ('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),  # 上下居中对齐
            ('LINEBELOW', (0, 0), (-1, -1), 0.5, colors.grey),  # 设置表格框线为grey色，线宽为0.5
        ]
        data_table = [[Paragraph(cell, tableContent) for cell in row] for row in model_table]
        content.append(Table(data_table, colWidths=colWidths, style=style, spaceAfter= 30))
    pdf.multiBuild(content)

def header(canvas, doc):
    """
    设置页眉
    :param canvas:Canvas类型  pdf画布
    :param doc:doc类型     整个pdf文件
    """
    if gshowpageHeader:
        Style = getSampleStyleSheet()
        title = Style['Title']
        # 自带样式不支持中文，需要设置中文字体，但有些样式会丢失，如斜体Italic。有待后续发现完全兼容的中文字体
        title.fontName = 'FZHTK'
        title.fontSize = 10
        canvas.saveState()
        n = Style['Normal']
        p = Paragraph(gpageHeader, title)
        w,h = p.wrap(doc.width, doc.bottomMargin)
        p.drawOn(canvas, doc.leftMargin, doc.bottomMargin + doc.height + 1 * cm)  # 放置报告这句话
        canvas.line(doc.leftMargin, doc.bottomMargin + doc.height + 1 * cm, doc.leftMargin + doc.width,
                    doc.bottomMargin + doc.height + 1 * cm)  # 画一条横线
        canvas.restoreState()

if __name__ == '__main__':
    exportPDF(None, None, None, None)
